/*
 * Created by Jaren at 2021/10/29 14:16
 */
import 'dart:typed_data';

import 'package:binary/binary.dart';
import 'package:inmotion_protocol/common/compact.dart';
import 'package:inmotion_protocol/common/product_model.dart';
import 'package:inmotion_protocol/common/product_version.dart';
import 'package:inmotion_protocol/lorin/bean/base/statistics.dart';
import 'package:inmotion_protocol/lorin/bean/common/date.dart';
import 'package:inmotion_protocol/util/byte_util.dart';

class EucTotalStatistics extends AbsTotalStatistics {
  Uint32 mileage = Uint32.zero;
  Uint32 energy = Uint32.zero;
  Uint32 powerOnTime = Uint32.zero;
  Uint32 recovery = Uint32.zero;
  Uint32 rideTime = Uint32.zero;

  EucTotalStatistics(ProductModel model, VersionWrapper version) : super(model, version);

  @override
  void initCompact() {
    compact = DefaultEucTotalStatics();
  }
}

class DefaultEucTotalStatics extends Compact<EucTotalStatistics> {
  @override
  void fromBytes(EucTotalStatistics output, Uint8ClampedList bytes, int offset) {
    if (bytes.length < offset + length()) {
      return;
    }
    output.mileage = ByteUtil.bytes2Uint32Le(bytes, offset);
    offset += 4;
    output.energy = ByteUtil.bytes2Uint32Le(bytes, offset);
    offset += 4;
    output.recovery = ByteUtil.bytes2Uint32Le(bytes, offset);
    offset += 4;
    output.rideTime = ByteUtil.bytes2Uint32Le(bytes, offset);
    offset += 4;
    output.powerOnTime = ByteUtil.bytes2Uint32Le(bytes, offset);
  }

  @override
  int length() {
    return 24;
  }
}

class EucStatistics extends AbsStatistics {
  Uint32 index = Uint32.zero;
  Datetime date = Datetime.emptyDate;
  Uint16 maxSpeed = Uint16.zero;
  Uint16 maxPower = Uint16.zero;
  Uint16 maxMotorPower = Uint16.zero;
  Int16 maxMosTemp = Int16.zero;
  Int16 maxMotorTemp = Int16.zero;
  Int16 maxBatteryTemp = Int16.zero;
  Int16 maxBoardTemp = Int16.zero;

  Uint32 mileage = Uint32.zero;
  Uint32 energy = Uint32.zero;
  Uint32 recovery = Uint32.zero;
  Uint32 rideTime = Uint32.zero;
  Uint32 powerOnTime = Uint32.zero;

  EucStatistics(ProductModel model, VersionWrapper version) : super(model, version);

  @override
  int statisticsOffset() {
    return 4;
  }

  @override
  void initCompact() {
    compact = DefaultEucStatics();
  }

  @override
  String toString() {
    return 'EucStatistics{index: $index, date: $date, maxSpeed: $maxSpeed, maxPower: $maxPower, maxMotorPower: $maxMotorPower, maxMosTemp: $maxMosTemp, maxMotorTemp: $maxMotorTemp, maxBatteryTemp: $maxBatteryTemp, maxBoardTemp: $maxBoardTemp, mileage: $mileage, energy: $energy, recovery: $recovery, rideTime: $rideTime, powerOnTime: $powerOnTime}';
  }
}

class DefaultEucStatics extends Compact<EucStatistics> {
  @override
  void fromBytes(EucStatistics output, Uint8ClampedList bytes, int offset) {
    if (bytes.length < offset + length()) {
      return;
    }
    output.index = ByteUtil.bytes2Uint32Le(bytes, offset);
    offset += 4;
    output.date = Datetime.fromBytes(bytes, offset: offset);
    offset += Datetime.length;
    output.maxSpeed = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    output.maxPower = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    output.maxMotorPower = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    output.maxMosTemp = ByteUtil.toInt16(ByteUtil.bytes2IntLe(bytes, offset) + 80);
    offset++;
    output.maxMotorTemp = ByteUtil.toInt16(ByteUtil.bytes2IntLe(bytes, offset) + 80);
    offset++;
    output.maxBatteryTemp = ByteUtil.toInt16(ByteUtil.bytes2IntLe(bytes, offset) + 80);
    offset++;
    output.maxBoardTemp = ByteUtil.toInt16(ByteUtil.bytes2IntLe(bytes, offset) + 80);
    offset++;
    output.mileage = ByteUtil.bytes2Uint32Le(bytes, offset);
    offset += 4;
    output.energy = ByteUtil.bytes2Uint32Le(bytes, offset);
    offset += 4;
    output.recovery = ByteUtil.bytes2Uint32Le(bytes, offset);
    offset += 4;
    output.rideTime = ByteUtil.bytes2Uint32Le(bytes, offset);
    offset += 4;
    output.powerOnTime = ByteUtil.bytes2Uint32Le(bytes, offset);
  }

  @override
  int length() {
    return 38;
  }
}
